package main

import (
	"fmt"
	"math/rand"
	"sort"
	"time"
)

// 第一题：
func firstHomework() {
	s1 := make([]int, 3, 4)
	s2 := append(s1, 1)
	//问：请问s1,s2内各有什么元素
	//答： s1 [0 0 0]  s2 [0 0 0 1]
	fmt.Printf("s1: %v %p %p %d %d\n", s1, &s1, &s1[0], len(s1), cap(s1))
	fmt.Printf("s2: %v %p %p %d %d\n", s2, &s2, &s2[0], len(s2), cap(s2))
	fmt.Println("~~~~~~~~~~~~~~~~~~~~~~~~~~")

	//问：s1 修改一个元素会影响s2吗？ s2修改一个元素会影响s1吗？
	//答： 修改s1一个元素会影响s2, 修改s2一个元素也会影响s1， 因为共用一个底层数组
	// s1[0] = 123
	s2[1] = 234
	// fmt.Println(s1, s2)
	// fmt.Printf("s2: %v %p %p\n", s2, &s2, &s2[0])
	fmt.Printf("s1: %v %p %p %d %d\n", s1, &s1, &s1[0], len(s1), cap(s1))
	fmt.Printf("s2: %v %p %p %d %d\n", s2, &s2, &s2[0], len(s2), cap(s2))
	fmt.Println("~~~~~~~~~~~~~~~~~~~~~~~~~~")

	// 问：s2 在增加一个元素会怎么样？
	// s2 再增加一个元素，会导致切片扩容， 因为底层数组长度不可变，
	// 所以会新生成一个新的底层数组， 因此s2的底层数组地址变了，标头值的len 和 cap 都会改变， 标头值的地址不会变；
	// s2扩容，s1不会扩容, s1的底层数组 len cap都还是和以前一样
	s2 = append(s2, 345)
	fmt.Printf("s2: %v %p %p %d %d\n", s2, &s2, &s2[0], len(s2), cap(s2))
	fmt.Printf("s1: %v %p %p %d %d\n", s1, &s1, &s1[0], len(s1), cap(s1))
}

// 第二题：有一个数组[1,4,9,16,2,5,10,15],生成一个新的切片，要求新切片元素是数组相邻2项的和
func secondHomework() {
	a := [...]int{1, 4, 9, 16, 2, 5, 10, 15}
	fmt.Println(a, len(a))

	var b = make([]int, 0, len(a))
	for i := 0; i < len(a)-1; i++ {
		b = append(b, a[i]+a[i+1])
	}
	fmt.Println(b)
}

// 第二题：
func secondHomework2(a [8]int) []int {
	b := make([]int, 0, len(a))
	for i := 1; i < len(a); i++ {
		b = append(b, a[i-1]+a[i])
	}
	return b
}

// 第三题：
// 数字重复统计
// 随机产生100个整数
// 数字范围[-100, 100]
// 降序输出这些生成的数字并打印其重复的次数
func RandomInt() {
	src := rand.NewSource(time.Now().UnixNano())
	r := rand.New(src)
	// var t int
	var m = make(map[int]int, 100)
	// var m map[int]int
	for i := 0; i < 100; i++ {
		// t = append(t, r.Intn(200)-100)
		t := r.Intn(200) - 100
		if n, ok := m[t]; !ok {
			m[t] = 1
		} else {
			m[t] = n + 1
		}
	}
	var keys = make([]int, 0, len(m))
	for key, _ := range m {
		keys = append(keys, key)
	}
	sort.Sort(sort.Reverse(sort.IntSlice(keys)))
	fmt.Println("降序排列出现随机数", "出现次数")
	for _, v := range keys {

		fmt.Printf("随机数是:%6d; %6d次\n", v, m[v])
	}

}

func main() {
	fmt.Println("~~~~~~~~~~第一题~~~~~~~~~~~~~~~~")
	firstHomework()
	fmt.Println("~~~~~~~~~~第二题~~~~~~~~~~~~~~~~")
	secondHomework()
	a := [...]int{1, 4, 9, 16, 2, 5, 10, 15}
	b := secondHomework2(a)
	fmt.Println(b)
	fmt.Println("~~~~~~~~~~第三题~~~~~~~~~~~~~~~~")
	RandomInt()
}


// 批改意见
// 1. 最后一题的范围漏掉了100，应该是Intn(201)-100。